<template>
  <!-- 头部返回 -->
  <van-nav-bar
    left-text="返回"
    left-arrow
    @click-left="$router.back()"
    fixed
    z-index="3"
  />
  <!-- 加载动画 -->
  <transition name="fade">
    <van-loading class="load" v-if="loading" color="#1989fa" />
  </transition>
  <transition name="fade">
    <div class="detail-container" v-if="!loading">
      <!-- 头部头像 -->
      <div class="uploader-container">
        <van-uploader
          v-model="fileList"
          max-count="1"
          :deletable="isEdit"
          @delete="changeImage"
        />
      </div>
      <!-- 信息表单 -->
      <div class="detail-form">
        <!-- 查看和编辑切换开关 -->
        <div class="edit-container">
          <span>编辑</span>
          <van-switch
            v-model="isEdit"
            size="0.6rem"
            @change="toggelEditSwitch"
          />
        </div>
        <van-form @submit="onSubmit" :readonly="!isEdit">
          <van-cell-group inset>
            <!-- 用户名 -->
            <van-field
              label-width="2rem"
              v-model="user.username"
              name="username"
              label="用户名"
              placeholder="用户名"
              left-icon="user-o"
              :disabled="isEdit"
            />
            <!-- 真实姓名 -->
            <van-field
              label-width="2rem"
              v-model="user.realname"
              name="realname"
              label="真实姓名"
              placeholder="请输入真实姓名"
              left-icon="idcard"
              :formatter="formatterTrim"
              :rules="[{ required: true, message: '请填写真实姓名' }]"
            />
            <!-- 性别 -->
            <van-field
              name="gender"
              label="性别"
              left-icon="friends-o"
              label-width="2rem"
            >
              <template #input>
                <van-radio-group
                  v-model="user.gender"
                  direction="horizontal"
                  :disabled="!isEdit"
                >
                  <van-radio name="1" shape="square"
                    >男生<span style="color: blue" class="genderTag"
                      >♂</span
                    ></van-radio
                  >
                  <van-radio name="0" shape="square"
                    >女生<span style="color: pink" class="genderTag"
                      >♀</span
                    ></van-radio
                  >
                </van-radio-group>
              </template>
            </van-field>
            <!-- 学校 -->
            <van-field
              label-width="2rem"
              v-model="user.college"
              name="college"
              label="学校"
              placeholder="请输入学校"
              :rules="[{ required: true, message: '请填写学校' }]"
              left-icon="hotel-o"
              :formatter="formatterTrim"
            />
            <!-- 专业 -->
            <van-field
              label-width="2rem"
              v-model="user.specialty"
              name="specialty"
              label="专业"
              placeholder="专业"
              left-icon="desktop-o"
              :formatter="formatterTrim"
              :rules="[{ required: true, message: '请填写专业' }]"
            />
            <!-- 年级 -->
            <van-field
              label-width="2rem"
              v-model="user.grade"
              name="grade"
              label="年级"
              placeholder="年级"
              left-icon="cluster-o"
              :formatter="formatterTrim"
            />
            <!-- 电话 -->
            <van-field
              label-width="2rem"
              v-model="user.phone"
              :formatter="formatterTrim"
              name="phone"
              label="电话"
              placeholder="电话"
              left-icon="phone-o"
              :rules="[
                {
                  validator: phoneValidator,
                  required: true,
                  message: '请输入正确电话',
                  trigger: 'onChange',
                },
              ]"
            />
            <!-- 短信验证码 -->
            <van-field
              label-width="2rem"
              v-if="isEdit"
              :formatter="formatterTrim"
              v-model="verfiedCode"
              name="verfiedCode"
              clearable
              label="短信验证码"
              left-icon="comment-o"
              placeholder="请输入验证码"
              :rules="[{ required: true, message: '请输入验证码' }]"
            >
              <template #button>
                <van-button
                  size="small"
                  type="primary"
                  :disabled="!user.phone || verfied.isSend || !canSend"
                  @click="sendVerfyCode"
                  >{{ verfied.vbtnMessage }}</van-button
                >
              </template>
            </van-field>
            <!-- 创建时间 -->
            <van-field
              label-width="2rem"
              v-model="user.createdAt"
              name="createdAt"
              label="创建时间"
              placeholder="创建时间"
              :disabled="isEdit"
              left-icon="clock-o"
            />
          </van-cell-group>
          <div style="margin: 16px">
            <!-- 登出 -->
            <van-button v-if="!isEdit" round block color="#aaa" @click="logout">
              登出
            </van-button>
            <!-- 保存编辑信息 -->
            <van-button v-else round block color="#1989fa" native-type="submit">
              保存
            </van-button>
          </div>
        </van-form>
      </div>
    </div>
  </transition>
</template>
<script>
import { getUserDetail, updateUserInfo } from '@/api/user.js'
import { isRegisted } from "@/api/UserBaseAPI/register.js"
import { uploadImage } from "@/utils/uploadImage"
import { cancelPromise } from "@/utils/cancelPromise.js"
import { sendVerfiedCode, reg_tel, VerfyingCode } from "@/utils/verifyCode.js";
import { clearStatus, changeCollege } from "@/utils/loginStatus.js";
import { reactive, toRefs, onMounted } from 'vue';
import { Form, Field, CellGroup, Button, RadioGroup, Radio, Switch, Loading, Toast, NavBar, Uploader }
  from 'vant';
import router from '../../router';
export default {
  name: 'user-detail',
  components: {
    [Form.name]: Form,
    [Field.name]: Field,
    [CellGroup.name]: CellGroup,
    [Button.name]: Button,
    [RadioGroup.name]: RadioGroup,
    [Radio.name]: Radio,
    [Switch.name]: Switch,
    [Loading.name]: Loading,
    [NavBar.name]: NavBar,
    [Uploader.name]: Uploader,
  },
  setup() {
    const pattern = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/
    const state = reactive({
      // 用户信息
      user: {
        username: '',
        gender: '',
        college: '',
        specialty: '',
        grade: '',
        realname: '',
        phone: '',
        createdAt: '',
        avatar: ''
      },
      // 是否加载状态
      loading: true,
      // 编辑状态
      isEdit: false,
      // uploader文件
      fileList: [{ url: '', isimage: true }],
      // 是否修改头像
      isChange: false,
      // 验证码
      verfiedCode: '',
      //是否能发送验证码
      canSend: true,
      // 电话正则
      pattern: /^(?:(?:\+|00)86)?1[3-9]\d{9}$/,
      //发送验证码
      verfied: {
        // 是否发送
        isSend: false,
        // 验证码按钮信息
        vbtnMessage: "发送验证码",
        vtime: 0,
      },
    })

    // 数据备份
    let _user = {}
    let _fileList = []

    onMounted(async () => {
      const res = await getUserDetail(sessionStorage.getItem('username'))
      state.user = res
      // 用户创建日期的转换
      state.user.createdAt = new Date(state.user.createdAt).toLocaleDateString()
      // 上传文件数组
      state.fileList = [{ url: state.user.avatar, isimage: true }]
      // 关闭loading
      state.loading = false
      // 数据备份
      _user = state.user
      // 解决gender为number的bug
      state.user.gender += ''
    })

    // 切换编辑开关
    const toggelEditSwitch = () => {
      if (state.isEdit) {
        // 数据备份
        _user = JSON.parse(JSON.stringify(state.user))
        _fileList = JSON.parse(JSON.stringify(state.fileList))
      }
      // 数据还原
      else {
        state.user = _user
        state.fileList = _fileList
        state.isChange = false
        state.verfiedCode = ''
      }
    }

    // 表单提交
    const onSubmit = (values) => {
      // 将头像删除时，没上传图片
      if (state.fileList.length === 0) {
        Toast.fail('请选择头像图片')
        return
      }
      // 将修改的信息存储，username默认携带（不携带验证码）
      let params = { username: state.user.username }
      Object.keys(values).forEach(key => {
        if (values[key] !== _user[key] && key !== 'verfiedCode') {
          params[key] = values[key]
        }
      })
      // 有修改时发起请求
      if (Object.keys(params).length !== 1 || state.isChange) {
        const toast1 = Toast.loading({
          duration: 0,
          forbidClick: true,
          message: "编辑中...",
          onOpened: async () => {
            // 验证码
            let veryfyRes = await VerfyingCode(values.phone, state.verfiedCode)
            if (veryfyRes.success) {
              // 头像修改
              if (state.isChange) {
                let file = state.fileList[0].file
                let data = await uploadImage(file.name, file)
                params.avatar = data.url;
              }
              if (params.college) {
                changeCollege(params.college)
              }
              const res = await updateUserInfo(params)
              state.isEdit = false
              state.verfiedCode = ''
              if (res.success) {
                toast1.clear();
                Toast.success('编辑成功！')
              }
              else {
                toast1.clear();
                Toast.fail('编辑失败！')
              }
            }
            else {
              toast1.clear();
              Toast.fail('验证码错误！')
            }
          }
        })
      }
      // 没有修改时不发起请求
      else {
        Toast({
          message: '没有进行信息编辑',
        });
        // 状态回退
        state.isEdit = false
        state.verfiedCode = ''
      }
    }
    // 表单内容格式化
    const formatterTrim = (value) => value.trim();
    // 是否修改头像
    const changeImage = () => {
      state.isChange = true
    }
    // 登出
    const logout = () => {
      clearStatus()
      router.push('/login');
    }
    //发送验证码
    const sendVerfyCode = () => {
      state.verfied.phone = state.user.phone
      sendVerfiedCode.call(state.verfied);
    }
    //电话号码校验
    const phoneValidator = () => {
      let phone = state.user.phone;
      if (!reg_tel.test(phone)) {
        state.canSend = false
        return "请输入正确的手机号"
      }
      return cancelPromise.request("phone", isRegisted({ type: 'phone', verfieditem: phone }).then(res => {
        if (res.isRegisted && phone !== _user.phone) {
          state.canSend = false
          return "该手机号已注册"
        }
        else {
          state.canSend = true
        }
      })
        .catch(err => {
          Toast.fail({
            duration: 1000,
            orbidClick: true,
            message: err
          })
          state.canSend = false
        }))
    }
    return {
      ...toRefs(state),
      toggelEditSwitch,
      onSubmit,
      pattern,
      formatterTrim,
      changeImage,
      logout,
      sendVerfyCode,
      phoneValidator,
    }
  }
}
</script>

<style lang="less" scoped >
// 表单及上传文件组件
:deep(.van-cell) {
  background-color: #f7f8fa;
}
:deep(.van-uploader__preview) {
  margin: 0;
  .van-uploader__preview-image {
    width: 100px;
    height: 100px;
    border-radius: 50%;
  }
}
:deep(.van-uploader),
:deep(.van-uploader__wrapper),
:deep(.van-uploader__upload),
:deep(.van-uploader__input) {
  width: 100px;
  height: 100px;
  margin: 0;
  background-color: #eee;
  border-radius: 50%;
}

.uploader-container {
  height: 100px;
  margin-bottom: 5px;
}
// 信息表单外部容器
.detail-container {
  background-color: #f7f8fa;
  box-sizing: border-box;
  padding-top: 50px;
  padding-bottom: 5px;
  outline: 900px solid #f7f8fa;
  // 信息表单
  .detail-form {
    width: 94%;
    margin: 0 10px;
    .edit-container {
      display: flex;
      justify-content: flex-end;
      span {
        font-size: 16px;
        padding-top: 3px;
        padding-right: 10px;
        font-weight: bold;
        letter-spacing: 2px;
      }
    }
  }
}
// 加载
.load {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  line-height: 100vh;
  background-color: #f7f8fa;
}
//性别选择标签
.genderTag {
  font-size: 16px;
  font-weight: bolder;
  padding-left: 1px;
}
// loading过度动画
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>